#include "imgproctab.h"
#include <imageloader.h>
#include <initmeasurement.h>
#include "ui_imgproctab.h"

ImgProcTab::ImgProcTab(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ImgProcTab)
{
    ui->setupUi(this);
    loaded = added = false;
    pos = max_pos = fileIndex = 0;
    seedtype = replicate = 0;
    roi = Rect(0,0,0,0);
    initm = new InitMeasurement;
    init();
}

ImgProcTab::~ImgProcTab()
{
    delete ui;
}
/*
 *	Initialize ui components
 *
 */
void ImgProcTab::init()
{
    ui->replicateBox->addItem("Select replication");
    ui->replicateBox->addItem("1");
    ui->replicateBox->addItem("2");
    ui->replicateBox->addItem("3");
    ui->replicateBox->addItem("4");

    ui->comboBox->addItem("Select method:");
    ui->comboBox->addItem("Skeletonization");
    ui->comboBox->addItem("Seed Area Analysis");
    ui->comboBox->addItem("Roundness analysis");
    ui->comboBox->addItem("Height analysis");

    ui->comboBox_2->addItem("Select image style");
    ui->comboBox_2->addItem("Gray Scale Image");
    ui->comboBox_2->addItem("Binary Image");

    connect(ui->replicateBox, SIGNAL(currentIndexChanged(int)), this, SLOT(selectMethod(int)));
    connect(ui->comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(run(int)));
    connect(ui->comboBox_2, SIGNAL(currentIndexChanged(int)), this, SLOT(showStyle(int)));
    connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(original()));
    connect(ui->pushButton_2, SIGNAL(clicked()), this, SLOT(enlarge()));
    connect(ui->boundButton, SIGNAL(clicked()), this, SLOT(showBoundBox()));
    connect(ui->contourButton, SIGNAL(clicked()), this, SLOT(showContour()));
    connect(ui->skeletonButton, SIGNAL(clicked()), this, SLOT(showSkeleton()));
    connect(ui->resultButton, SIGNAL(clicked()), this, SLOT(showResult()));
    connect(initm, SIGNAL(finished()), this, SLOT(done()));
}

/*
 *
 *
 */
void ImgProcTab::done()
{
    int currInd = imgL->getCurrIndex();

    if(currInd > 7)
    {
        result_img = initm->getResultImg();
        contour_img = initm->getContourImg();
        ske_img = initm->getSkeImg();
        gray_img = initm->getGrayImg();
        bin_img = initm->getBinImg();
        bound_img = initm->getResultImg();

        display(result_img);

        ui->totalLabel->setText(QString::number(initm->getNumGerm()));
        ui->comboBox_2->setEnabled(true);

        if(!ui->resultButton->isEnabled())
            ui->resultButton->setEnabled(true);
        if(!ui->boundButton->isEnabled())
            ui->boundButton->setEnabled(true);
        if(!ui->skeletonButton->isEnabled())
            ui->skeletonButton->setEnabled(true);
        if(!ui->contourButton->isEnabled())
            ui->contourButton->setEnabled(true);
    }
    else if(currInd < 7)
    {
        QMessageBox msgBox;
        msgBox.setText("You have selected an initial image");
        msgBox.exec();
    }

    reset(1);
}

void ImgProcTab::addLoader(ImageLoader *imgL)
{
    if(imgL)
    {
        this->imgL = imgL;
        added = true;
    }
}

// Display current image of 'imageloader'
void ImgProcTab::showContent()
{
    QString curr_file;

    if(added)
    {
        curr_file = imgL->getCurrFile();
    }

    if(curr_file.length() > 0)
    {
        img = imread(curr_file.toStdString());

        display(img);
        calcHistogram(img);

        // An image has been loaded
        loaded = true;
        // original image button
        ui->pushButton->setEnabled(true);
    }
}


void ImgProcTab::selectMethod(int index)
{
    if(index > 0)
    {
        ui->comboBox->setEnabled(true);
        replicate = index;
    }
}

void ImgProcTab::run(int index)
{
    if(loaded)
    {
        if(index > 0)
        {
            doAnalysis(seedtype, replicate, index);
        }
    }
}

void ImgProcTab::showStyle(int index)
{
    // Convert to gray image
    if(index == 1)
    {
        if(loaded) toGray();
    }
    // Convert to binary image
    else if(index == 2)
    {
        if(loaded) toBin();
    }
    reset(2);
}

void ImgProcTab::showResult()
{
    display(result_img);
}

void ImgProcTab::showBoundBox()
{   
    display(bound_img);
}

void ImgProcTab::showContour()
{
    display(contour_img);
}

void ImgProcTab::showSkeleton()
{
    if(ske_img.data)
    {
        bitwise_not(ske_img, ske_img);
    }
    display(ske_img);
}

void ImgProcTab::original()
{
    if(loaded)
        display(img);
}

// Display gray level image of color space value
void ImgProcTab::toGray()
{
    display(gray_img);

}

void ImgProcTab::toBin()
{
    display(bin_img);
}

void ImgProcTab::enlarge()
{
    if(label_img.data)
    {
        namedWindow("Enlarge", 1);
        imshow("Enlarge", label_img);
        waitKey(-1);
        destroy("Enlarge");
    }
}

void ImgProcTab::display(const Mat& img)
{
    // Check if img is valid
    if(!img.data) return;

    label_img = img.clone();
    Mat clone;
    img.copyTo(clone);

    if(clone.channels() == 1)
        cvtColor(img, clone, CV_GRAY2RGB);
    else
        cvtColor(img, clone, CV_BGR2RGB);

    QImage qTemp = QImage(clone.data, clone.cols, clone.rows, clone.step, QImage::Format_RGB888);
    if(qTemp.isNull()) return;
    else qTemp = qTemp.scaled(ui->imageLabel->size(), Qt::KeepAspectRatio);

    ui->imageLabel->setPixmap(QPixmap::fromImage(qTemp, 0));
    ui->pushButton_2->setEnabled(true);

    imgL->addResultImg(img);
}

// This method is safe
void ImgProcTab::calcHistogram(const Mat& img)
{
    // Check if img is valid
    if(!img.data) return;

    Mat hsv;
    cvtColor(img, hsv, CV_BGR2HSV);

    double maxVal = 0;

    int hbins=20, vbins=12;
    int histSize[] = {hbins, vbins};
    float hranges[] = {0, 180};
    float vranges[] = {0, 255};
    const float* ranges[] = {hranges, vranges};

    MatND hist;
    // compute the histogram from 0-th and 2-nd channels
    int channels[] = {0, 2};

    calcHist(&hsv, 1, channels, Mat(), hist, 2, histSize, ranges, true, false);
    minMaxIdx(hist, 0, &maxVal, 0, &max_pos);

    // seedtype - 1 for light seeds
    // seedtype - 2 for dark seeds
    seedtype = 2 - max_pos;

    QString type = seedtype == 1? "Light seeds" : "Dark seeds";
    type = "Seed type " + type;
    qDebug(type.toStdString().c_str());
}

void ImgProcTab::doAnalysis(int seed, int rep, int method)
{
    initm->addInfo(imgL, seed, rep, method);
    initm->start();
}

// Reset combo box to default value
void ImgProcTab::reset(int index)
{
    if(index == 1)
    {
        ui->replicateBox->setCurrentIndex(0);
        ui->comboBox->setCurrentIndex(0);
    }
    else if(index == 2)
        ui->comboBox_2->setCurrentIndex(0);
}
